package triangle;

public class Triangle {

	private double side_a;
	private double side_b;
	private double side_c;
	
	private double angle_a;
	private double angle_b;
	private double angle_c;
	
	/**
	 * Creates a new instance of Triangle given the information on the three sides.
	 * 
	 * @param side1 - First side of the triangle.
	 * @param side2 - Second side of the triangle.
	 * @param side3 - Third side of the triangle.
	 */
	public Triangle(double side1, double side2, double side3){
		this.side_a = side1;
		this.side_b = side2;
		this.side_c = side3;
		
		angle_a = 0.0;
		angle_b = 0.0;
		angle_c = 0.0;
	}
	
	/** 
	 * Returns true if the triangle is a right triangle.
	 * 
	 * @return
	 */
	public boolean isRightTriangle(){
		
		// Check if it is a triangle
		if(!isTriangle())
			return false;
		
		if(angle_a == 90.0)
			return true;
		else if(angle_b == 90.0)
			return true;
		else if(angle_c == 90.0)
			return true;
		
		return false;
	}
	
	/**
	 * Returns true if the triangle is an equilateral triangle.
	 * 
	 * @return
	 */
	public boolean isEquilateralTriangle(){
		
		// Check if it is a triangle
		if(!isTriangle())
			return false;
		
		// Check if sides are equal
		// IF a == b and a == c, then b == c
		if(side_a == side_b && side_a == side_c)
			return true;
		
		return false;
	}
	
	/**
	 * Returns true if the triangle is an isoceles triangle.
	 * 
	 * @return
	 */
	public boolean isIsocelesTriangle(){
		
		// Check if it is a triangle
		if(!isTriangle())
			return false;
		
		// Check if two sides are equal, but not three
		if(side_a == side_b && side_a != side_c)
			return true;
		else if(side_a == side_c && side_a != side_b)
			return true;
		else if(side_b == side_c && side_b != side_a)
			return true;
		
		return false;
	}
	
	/**
	 * Returns true if the triangle is a scalene triangle.
	 * 
	 * @return
	 */
	public boolean isScaleneTriangle(){
		
		// Check if it is a triangle
		if(!isTriangle())
			return false;
		
		// Check that all sides are different
		if(side_a != side_b && side_a != side_c && side_b != side_c)
			return true;
		
		return false;
	}
	
	/** 
	 * Returns true if the triangle is an actual triangle.
	 * 
	 * @return
	 */
	public boolean isTriangle(){
		// Check sides to make sure each side is more than the difference
		// of the other two sides, but less than the sum
		if( (side_a < Math.abs(side_b - side_c)) || (side_a > (side_b + side_c)) )
			return false;
		if( (side_b < Math.abs(side_a - side_c)) || (side_b > (side_a + side_c)) )
			return false;
		if( (side_c < Math.abs(side_a - side_b)) || (side_c > (side_a + side_b)) )
			return false;
		
		//System.out.println("Triangle based on sides");
		
		double factor = 1e6;
		
		// Calculate Angle A
		angle_a = Math.round(Math.toDegrees(Math.acos( ((side_b * side_b) + (side_c * side_c) - (side_a * side_a)) / (2 * side_b * side_c))) * factor) / factor;
		
		if(angle_a <= 0 || angle_a >= 180)
			return false;
		
		//System.out.println("Angle A:" + angle_a);
		
		// Calculate Angle B
		angle_b = Math.round(Math.toDegrees(Math.acos( ((side_a * side_a) + (side_c * side_c) - (side_b * side_b)) / (2 * side_a * side_c))) * factor) / factor;
		
		if(angle_b <= 0 || angle_b >= 180)
			return false;
		
		//System.out.println("Angle B:" + angle_b);
		
		// Calculate Angle C
		angle_c = Math.round(Math.toDegrees(Math.acos( ((side_a * side_a) + (side_b * side_b) - (side_c * side_c)) / (2 * side_a * side_b))) * factor) / factor;
		
		if(angle_c <= 0 || angle_c >= 180)
			return false;
		
		//System.out.println("Angle C:" + angle_c);
		
		//System.out.println("Sum of angles: " + (angle_a + angle_b + angle_c));
		
		// Check all the angles to make sure the sum is equal to 180.
		// This isn't the best way to do it, obviously, but its a start
		if ((angle_a + angle_b + angle_c) != 180.0)
			return false;
		
		return true;
	}
	
	/**
	 * Returns an array containing the sides of the triangle.
	 * 
	 * @return - double array containing the three sides of the triangle.
	 */
	public double[] sidesOfTriangle(){
		return new double[]{side_a,side_b,side_c};
	}
	
}
